package com.cupdata.marathon.service.impl;

import com.cupdata.marathon.bean.Result;
import com.cupdata.marathon.client.AcctOperService;
import com.cupdata.marathon.client.MemberCheckService;
import com.cupdata.marathon.common.AuthCheckService;
import com.cupdata.marathon.common.KafkaSender;
import com.cupdata.marathon.common.RedisService;
import com.cupdata.marathon.common.UserInfoCheckService;
import com.cupdata.marathon.definition.*;
import com.cupdata.marathon.entity.TblRetryTransLog;
import com.cupdata.marathon.generator.CouponIdGenerator;
import com.cupdata.marathon.param.acctoper.AcctOperRequest;
import com.cupdata.marathon.param.acctoper.AcctOperResponse;
import com.cupdata.marathon.param.download.DownloadRequest;
import com.cupdata.marathon.param.download.DownloadResponse;
import com.cupdata.marathon.param.membercheck.MemCheckRequest;
import com.cupdata.marathon.param.membercheck.MemCheckResponse;
import com.cupdata.marathon.service.CouponService;
import com.cupdata.marathon.service.ITblHackCouponDownTransLogService;
import com.cupdata.marathon.utils.GsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

import static com.cupdata.marathon.config.ConfigConstans.ACCESS_ID;
import static com.cupdata.marathon.config.ConfigConstans.SYS_ID;

@Service
public class CouponServiceImpl implements CouponService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    AuthCheckService authCheckService;
    @Autowired
    RedisService redisService;
    @Autowired
    MemberCheckService memberCheckService;
    @Autowired
    AcctOperService acctOperService;
    @Autowired
    ITblHackCouponDownTransLogService hackCouponDownTransLogService;
    @Autowired
    private UserInfoCheckService userInfoCheckService;
    @Autowired
    KafkaSender kafkaSender;

    @Value(value = "${topicName.topicRetry}")
    private String topicRetry;

    //用户会员检查
    @Override
    public DownloadResponse call(DownloadRequest request) {
        long sysStart = System.currentTimeMillis();
        logger.info("#########优惠券下载服务traceId-[{}]开始#########", request.getTransId());
        DownloadResponse response = new DownloadResponse();
        response.setTransId(request.getTransId());
        response.setRspCd(RspCd.SUCCESS.getCode());
        try {
            MemCheckRequest memCheckRequest = new MemCheckRequest();
            memCheckRequest.setTransId(request.getTransId());
            memCheckRequest.setUserId(request.getUserId());
            //会员服务
            MemCheckResponse memCheckResponse = memberCheckService.call(memCheckRequest);
            if (RspCd.SUCCESS.getCode().equals(memCheckResponse.getRspCd())) {
                if (MemTp.ERROR.getCode().equals(memCheckResponse.getOperRslt())) {
                    response.setMemTp(MemTp.NON_MEMBER.getCode());
                    response.setDownRslt(DownRslt.R200090.getCode());
                    response.setRspMsg(DownRslt.R200090.getMsg());
                    response.setTransId(request.getTransId());
                    return response;
                }
                response.setMemTp(memCheckResponse.getOperRslt());
            } else {
                response.setMemTp(MemTp.NON_MEMBER.getCode());
                response.setDownRslt(DownRslt.R200099.getCode());
                response.setRspMsg(DownRslt.R200099.getMsg());
                return response;
            }

            Result result = authCheckService.districtCheck(request);
            if (!"0000".equals(result.getCode())) {
                response.setDownRslt(result.getCode());
                response.setRspMsg(result.getMessage());
                hackCouponDownTransLogService.save(request, response, LocalDateTime.now());
                return response;
            }
            // 判断优惠券剩余总数
            if(!redisService.couponRemainsExist(request.getCouponTp())) {
                response.setRspMsg(DownRslt.R000001.getMsg());
                response.setDownRslt(DownRslt.R000001.getCode());
                hackCouponDownTransLogService.save(request, response, LocalDateTime.now());
                return response;
            }
            // 验证用户信息
            Result checkResult = userInfoCheckService.userInfoCheck(request.getUserId(),request.getTransId());
            if (checkResult != null) {
                if (RspCd.FAIL.getCode().equals(checkResult.getCode())) {
                    response.setRspMsg(DownRslt.R100099.getMsg());
                    response.setDownRslt(DownRslt.R100099.getCode());
                    hackCouponDownTransLogService.save(request, response, LocalDateTime.now());
                    return response;
                } else {
                    response.setRspMsg(checkResult.getMessage());
                    response.setDownRslt(OperUserRslt.getDownRslt(checkResult.getCode()));
                    hackCouponDownTransLogService.save(request, response, LocalDateTime.now());
                    return response;
                }
            }

            // 校验用户已领取优惠券数目和总额
            Result handleResult = redisService.userCouponCheck(request.getUserId(), request.getCouponTp(),
                    memCheckResponse.getOperRslt());
            if (!(DownRslt.R000000.getCode().equals(handleResult.getCode()))) {
                response.setRspMsg(handleResult.getMessage());
                response.setDownRslt(handleResult.getCode());
                hackCouponDownTransLogService.save(request, response, LocalDateTime.now());
                return response;
            }

            // 扣减优惠券
            if (!redisService.deductCoupon(request.getCouponTp())) {
                //券已用完
                response.setRspMsg(DownRslt.R000001.getMsg());
                response.setDownRslt(DownRslt.R000001.getCode());
                hackCouponDownTransLogService.save(request, response, LocalDateTime.now());
                return response;
            }

            //TODO ID池化
            response.setCouponId(CouponIdGenerator.generate(request));

            //动账操作
            AcctOperRequest acctOperRequest = new AcctOperRequest();
            acctOperRequest.setSysId(SYS_ID);
            acctOperRequest.setAccessId(ACCESS_ID);
            acctOperRequest.setAcctTp("UP02");
            acctOperRequest.setCouponId(response.getCouponId());
            acctOperRequest.setCouponTp(request.getCouponTp());
            acctOperRequest.setRemark("success");
            acctOperRequest.setTransTime(request.getTransTime());
            acctOperRequest.setUserId(request.getUserId());
            acctOperRequest.setTransId(request.getTransId());

            AcctOperResponse acctOperResponse = acctOperService.call(acctOperRequest);
            if (RspCd.SUCCESS.getCode().equals(acctOperResponse.getRspCd())) {
                response.setRspMsg(RspCd.SUCCESS.getMsg());
                response.setDownRslt(DownRslt.R000000.getCode());
                if (!OperAcctRslt.OA0000.getCode().equals(acctOperResponse.getOperRslt())){
                    if (OperAcctRslt.OA0010.getCode().equals(acctOperResponse.getOperRslt())) {
                        response.setDownRslt(DownRslt.R300010.getCode());
                        response.setRspMsg(DownRslt.R300010.getMsg());
                    }
                    if (OperAcctRslt.OA0090.getCode().equals(acctOperResponse.getOperRslt())) {
                        response.setDownRslt(DownRslt.R300090.getCode());
                        response.setRspMsg(DownRslt.R300090.getMsg());
                    }
                    hackCouponDownTransLogService.save(request, response, LocalDateTime.now());
                    redisService.restoreCoupon(request);
                    return response;
                    }
            } else {
                response.setRspMsg(DownRslt.R300099.getMsg());
                response.setDownRslt(DownRslt.R300099.getCode());
                saveRetrylog(request, response);
                return response;
            }
            hackCouponDownTransLogService.save(request, response, LocalDateTime.now());
            return response;
        } catch (Exception e) {
            e.printStackTrace();
            response.setRspCd(RspCd.FAIL.getCode());
            response.setRspMsg(RspCd.FAIL.getMsg());
            hackCouponDownTransLogService.save(request, response, LocalDateTime.now());
            return response;
        } finally {
            logger.info("#########优惠券下载服务traceId-[{}]结束[{}ms]#########", request.getTransId(), System.currentTimeMillis() - sysStart);
        }
    }

    private void saveRetrylog(DownloadRequest request, DownloadResponse response) {
        TblRetryTransLog retryTransLog = new TblRetryTransLog();
        retryTransLog.setSysId(SYS_ID);
        retryTransLog.setAccessId(ACCESS_ID);
        retryTransLog.setUserId(request.getUserId());
        retryTransLog.setCouponId(response.getCouponId());
        retryTransLog.setTransId(request.getTransId());
        retryTransLog.setCouponTp(request.getCouponTp());
        retryTransLog.setAcctTp("UP02");
        hackCouponDownTransLogService.save(request, response, LocalDateTime.now());
        kafkaSender.sendMessage(topicRetry, GsonUtils.gson.toJson(retryTransLog));

//        tblRetryTransLogService.saveOrUpdate(retryTransLog);
    }


}
